package cn.innosmart.aq.customize;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import com.zhy.autolayout.utils.AutoUtils;

import java.util.ArrayList;

import cn.innosmart.aq.R;

/**
 * Created by Woody on 2015/4/10.
 */
public class CustomNavigationBar extends View {
    private static final int DIRECTION_LEFT = 0;
    private static final int DIRECTION_RIGHT = 1;
    private Bitmap mBGImage;
    private Bitmap mBGArrow;
    private int sectionSize;
    private String[] sectionText;
    private Paint mPaint;
    private Rect rect;
    private Paint mTextPaint;
    private float mTextSize;
    private Rect mTextRect;
    private ArrayList<Path> mSectionArrowPaths;
    private ArrayList<String> mSectionNames;
    private ArrayList<Path> mSectionArrowBorders;
    //position   currentIndex
    private int position = 0;
    private int currentIndex = 0;
    private Paint mBgPaint;
    private Paint mArrowBorderPaint;
    private Paint mArrowPathPaint;
    private Paint mArrowBoderPaint;
    private Path mSectionArrowPath;
    private Path mSectionArrowBorder;
    private int mTextOriginColor;
    private int mTextChangeColor;
    private int mArrowOriginColor;
    private int mArrowChangeColor;
    private int mArrowBoderColor;
    private int mDirection = DIRECTION_LEFT;
    private float mProgress;
    private int mWidth;
    private int mHeight;

    public CustomNavigationBar(Context context) {
        this(context, null);
    }

    public CustomNavigationBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public CustomNavigationBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomNavigationBar, defStyle, 0);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.CustomNavigationBar_image:
                    mBGImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
                    break;
                case R.styleable.CustomNavigationBar_sectionSize:
                    sectionSize = a.getInt(attr, 0);
                    break;
                case R.styleable.CustomNavigationBar_sectionText:
                    sectionText = a.getString(attr).split(",");
                    break;
                case R.styleable.CustomNavigationBar_direction:
                    mDirection = a.getInt(attr, mDirection);
                    break;
                case R.styleable.CustomNavigationBar_sectionTextSize:
//                    mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16, getResources().getDisplayMetrics()));
                    mTextSize = AutoUtils.getPercentHeightSize(37);
                    break;
                case R.styleable.CustomNavigationBar_sectionArrowOriginColor:
                    mArrowOriginColor = a.getColor(attr, Color.parseColor("#FF8bc34a"));
                    break;
                case R.styleable.CustomNavigationBar_sectionArrowChangedColor:
                    mArrowChangeColor = a.getColor(attr, Color.WHITE);
                    break;
                case R.styleable.CustomNavigationBar_sectionTextOriginColor:
                    mTextOriginColor = a.getColor(attr, Color.WHITE);
                    break;
                case R.styleable.CustomNavigationBar_sectionTextChangedColor:
                    mTextChangeColor = a.getColor(attr, Color.parseColor("#FF8bc34a"));
                    break;
                case R.styleable.CustomNavigationBar_sectionArrowBorderColor:
                    mArrowBoderColor = a.getColor(attr, Color.parseColor("#FFe0e0e0"));
                    break;
            }
        }
        a.recycle();
        mSectionArrowPaths = new ArrayList<Path>();
        mSectionNames = new ArrayList<String>();
        mSectionArrowBorders = new ArrayList<Path>();
        mBgPaint = new Paint();
        mBgPaint.setAntiAlias(true);
        mArrowPathPaint = new Paint();
        mArrowPathPaint.setAntiAlias(true);
        mArrowBorderPaint = new Paint();
        mArrowBorderPaint.setAntiAlias(true);
        rect = new Rect();
        mTextRect = new Rect();
        mTextPaint = new Paint();
        mTextPaint.setColor(Color.parseColor("#FF8bc34a"));
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.getTextBounds(sectionText[0], 0, sectionText[0].length(), mTextRect);
        mBGArrow = BitmapFactory.decodeResource(getResources(), R.drawable.rule_step_arrow);
    }

    private static Bitmap scaleBitmap(Bitmap bitmap, float widthSacle, float heightScale) {
        Matrix matrix = new Matrix();
        matrix.postScale(widthSacle, heightScale); //���Ϳ�Ŵ���С�ı���
        Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizeBmp;
    }

    public void setDirection(int direction) {
        mDirection = direction;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mWidth = measureWidth(widthMeasureSpec);
        mHeight = measureHeight(heightMeasureSpec);
        if (mBGImage != null) {
            mBGImage = scaleBitmap(mBGImage, ((float) mWidth / mBGImage.getWidth()), ((float) mHeight / mBGImage.getHeight()));
        }
        calculatePaths(mWidth, mHeight);
        setMeasuredDimension(mWidth, mHeight);
    }

    private int measureHeight(int measureSpec) {
        int mode = MeasureSpec.getMode(measureSpec);
        int val = MeasureSpec.getSize(measureSpec);
        int result = 0;
        switch (mode) {
            case MeasureSpec.EXACTLY:
                result = val;
                break;
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
//                result = mTextBound.height();
                break;
        }
//        result = mode == MeasureSpec.AT_MOST ? Math.min(result, val) : result;
        result = val;
        return result + getPaddingTop() + getPaddingBottom();
    }

    private int measureWidth(int measureSpec) {
        int mode = MeasureSpec.getMode(measureSpec);
        int val = MeasureSpec.getSize(measureSpec);
        int result = 0;
        switch (mode) {
            case MeasureSpec.EXACTLY:
                result = val;
                break;
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
                // result = mTextBound.width();
//                result = mTextWidth;
                break;
        }
//        result = mode == MeasureSpec.AT_MOST ? Math.min(result, val) : result;
        result = val;
        return result + getPaddingLeft() + getPaddingRight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mBGImage != null) {
            canvas.drawBitmap(mBGImage, 0, 0, mBgPaint);
        }
//        mArrowPathPaint.setColor(mArrowChangeColor);
//        mArrowBorderPaint.setColor(mArrowBoderColor);
//        for (int i = 0; i <= position; i++) {
//            canvas.drawPath(mSectionArrowPaths.get(i), mArrowPathPaint);
//        }
        for (int i = 0; i < sectionSize - 1; i++) {
            canvas.drawBitmap(mBGArrow, mWidth * (i + 1) / sectionSize - mBGArrow.getWidth() / 2, mHeight / 2 - mBGArrow.getHeight() / 2, mBgPaint);
        }
//        drawLeftOrighinText(canvas);
        if (position == (sectionSize - 1)) {
            drawLeftOriginBackground(canvas);
        } else if (currentIndex == position) {
            drawLeftOriginBackground(canvas);
            drawChangeLeft(canvas);
        } else {
            drawRightOriginBackground(canvas);
            drawChangeRight(canvas);
        }
    }


    private void drawLeftOrighinText(Canvas canvas) {
        for (int i = 0; i < sectionSize; i++) {
            String text = sectionText[i];
            if (i <= position) {
                mTextPaint.setColor(mTextChangeColor);
            } else {
                mTextPaint.setColor(mTextOriginColor);
            }
            canvas.drawText(text, (mWidth / 6 + mWidth * i / 3), mHeight / 2 + mTextRect.height() / 3, mTextPaint);
            canvas.save();
        }
    }

    private void drawRightOrighinText(Canvas canvas) {
        for (int i = 0; i < sectionSize; i++) {
            String text = sectionText[i];
            if (i <= currentIndex) {
                mTextPaint.setColor(mTextChangeColor);
            } else {
                mTextPaint.setColor(mTextOriginColor);
            }
            canvas.drawText(text, (mWidth / 6 + mWidth * i / 3), mHeight / 2 + mTextRect.height() / 3, mTextPaint);
            canvas.save();
        }
    }


    private void drawChangeLeft(Canvas canvas) {
        mArrowPathPaint.setColor(mArrowChangeColor);
        if (position == (sectionSize - 2)) {
            canvas.clipRect((int) (mWidth * (position + 1) / 3 - mHeight / 3), 0, (int) (mProgress * (mWidth / 3 + mHeight / 3) + (mWidth * (position + 1) / 3 - mHeight / 3)), getMeasuredHeight());
        } else {
            canvas.clipRect((mWidth * (position + 1) / 3 - mHeight / 3), 0, (int) (mProgress * (mWidth / 3 + mHeight * 2 / 3) + (mWidth * (position + 1) / 3 - mHeight / 3)), getMeasuredHeight());
        }
        String text = sectionText[position + 1];
        mTextPaint.setColor(mTextChangeColor);
        canvas.drawText(text, (mWidth / 6 + mWidth * (position + 1) / 3), mHeight / 2 + mTextRect.height() / 3, mTextPaint);
    }

    private void drawChangeRight(Canvas canvas) {
        mArrowPathPaint.setColor(mArrowOriginColor);
        if (position == (sectionSize - 2)) {
            canvas.clipRect((mWidth - ((1 - mProgress) * (mWidth / sectionSize + mHeight / 3))), 0, mWidth, getMeasuredHeight());
        } else {
            canvas.clipRect(((mWidth * (currentIndex + 1) / sectionSize + mHeight / 3) - ((1 - mProgress) * (mWidth / sectionSize + mHeight * 2 / 3))), 0, (mWidth * (currentIndex + 1) / sectionSize + mHeight / 3), getMeasuredHeight());
        }
        String text = sectionText[currentIndex];
        mTextPaint.setColor(mTextOriginColor);
        canvas.drawText(text, (mWidth / 6 + mWidth * (currentIndex) / 3), mHeight / 2 + mTextRect.height() / 3, mTextPaint);
    }

    public float getProgress() {
        return mProgress;
    }

    public void setProgress(float progress) {
        this.mProgress = progress;
        invalidate();
    }

    private void drawBackText(Canvas canvas) {
        for (int i = 0; i < sectionText.length; i++) {
            String text = sectionText[i];
            canvas.drawText(text, (mWidth / 6 + mWidth * i / 3), 5, mTextPaint);
            canvas.save();
        }
    }

    //�ⲿ���ø�Change����������
    public void changing(int position, int currentIndex, float progress) {
        this.position = position;
        this.currentIndex = currentIndex;
        setProgress(progress);
    }

    /**
     * ��Ҫ��
     * 1������
     * 2��PathArrow
     * 3��PathBorder
     * 4����������
     */
    private void drawLeftOriginBackground(Canvas canvas) {
        drawLeftOrighinText(canvas);
    }

    private void drawRightOriginBackground(Canvas canvas) {
        drawRightOrighinText(canvas);
    }

    private void calculatePaths(int mWidth, int mHeight) {
        for (int i = 0; i < sectionSize; i++) {
            if (i == sectionSize - 1) {
                addSectionArrowPath(-1);
            } else {
                addSectionArrowPath(i);
                addSectionArrowBorder(i);
            }
        }

    }

    /**
     * @param position ���Ϊ-1��Ϊ���һ��
     */
    private void addSectionArrowPath(int position) {
        mSectionArrowPath = new Path();
        if (position == 0) {
            mSectionArrowPath.moveTo(2, 2);
            mSectionArrowPath.lineTo(mWidth / sectionSize - mHeight / 3, 2);
            mSectionArrowPath.lineTo(mWidth / sectionSize + mHeight / 3, mHeight / 2);
            mSectionArrowPath.lineTo(mWidth / sectionSize - mHeight / 3, mHeight - 2);
            mSectionArrowPath.lineTo(2, mHeight - 2);
            mSectionArrowPath.close();
        } else if (position == -1) {
            mSectionArrowPath.moveTo(mWidth * (sectionSize - 1) / sectionSize - mHeight / 3 + 5, 2);
            mSectionArrowPath.lineTo(mWidth - 2, 2);
            mSectionArrowPath.lineTo(mWidth - 2, mHeight - 2);
            mSectionArrowPath.lineTo(mWidth * (sectionSize - 1) / sectionSize - mHeight / 3 + 5, mHeight - 2);
            mSectionArrowPath.lineTo(mWidth * (sectionSize - 1) / sectionSize + mHeight / 3 + 5, mHeight / 2);
            mSectionArrowPath.close();
        } else {
            mSectionArrowPath.moveTo(mWidth * position / sectionSize - mHeight / 3 + 5, 2);
            mSectionArrowPath.lineTo(mWidth * (position + 1) / sectionSize - mHeight / 3, 2);
            mSectionArrowPath.lineTo(mWidth * (position + 1) / sectionSize + mHeight / 3, mHeight / 2);
            mSectionArrowPath.lineTo(mWidth * (position + 1) / sectionSize - mHeight / 3, mHeight - 2);
            mSectionArrowPath.lineTo(mWidth * position / sectionSize - mHeight / 3 + 5, mHeight - 2);
            mSectionArrowPath.lineTo(mWidth * position / sectionSize + mHeight / 3 + 5, mHeight / 2);
            mSectionArrowPath.close();
        }
        mSectionArrowPaths.add(mSectionArrowPath);
    }

    private void addSectionArrowBorder(int position) {
        mSectionArrowBorder = new Path();
        mSectionArrowBorder.moveTo(mWidth * (position + 1) / sectionSize - mHeight / 3, 2);
        mSectionArrowBorder.lineTo(mWidth * (position + 1) / sectionSize - mHeight / 3 + 5, 2);
        mSectionArrowBorder.lineTo(mWidth * (position + 1) / sectionSize + mHeight / 3 + 5, mHeight / 2);
        mSectionArrowBorder.lineTo(mWidth * (position + 1) / sectionSize - mHeight / 3 + 5, mHeight - 2);
        mSectionArrowBorder.lineTo(mWidth * (position + 1) / sectionSize - mHeight / 3, mHeight - 2);
        mSectionArrowBorder.lineTo(mWidth * (position + 1) / sectionSize + mHeight / 3, mHeight / 2);
        mSectionArrowBorder.close();
        mSectionArrowBorders.add(mSectionArrowBorder);
    }

    public enum Direction {
        LEFT, RIGHT;
    }

}
